#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
@Project ：HiflyVideoAPI_Test 
@File    ：utils_task.py
@Author  ：beibei
@Date    ：2025/6/13 3:39 PM 
'''
import subprocess
# utils/task_monitor.py

import time
import json
from pathlib import Path
from threading import Thread
from datetime import datetime
from urllib.parse import urlencode
import time
import os
from urllib.parse import urlencode


import requests

from common.assertCommon import AssertCommon
from common.caseOutput import info


def get_project_root():
    """
    自动获取项目根目录，支持本地与 Jenkins 任务路径
    """
    env_root = os.environ.get("PROJECT_ROOT")
    if env_root and Path(env_root).exists():
        return Path(env_root)

    current = Path(__file__).resolve()
    for parent in current.parents:
        if (parent / "requirements.txt").exists() and (
            (parent / "common").is_dir() or (parent / "testCase").is_dir()
        ):
            return parent

    raise RuntimeError("❌ 未找到项目根目录，请检查目录结构或设置 PROJECT_ROOT")

def save_task_id(task_id: str, filename: str = None, source: str = "", task_type: str = ""):
    """
        保存 task_id 到文件和 task_history.json，并支持区分任务类型
        """
    root = get_project_root()

    if not filename:
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = f"data/tasks/task_{timestamp}.json"

    output_path = root / filename
    output_path.parent.mkdir(parents=True, exist_ok=True)

    with open(output_path, "w", encoding="utf-8") as f:
        json.dump({"task_id": task_id}, f, ensure_ascii=False, indent=2)
    info(f"task_id 已保存至: {output_path}")

    # 写入 task_history.json
    history_path = root / "data/tasks/task_history.json"
    history = []
    if history_path.exists():
        with open(history_path, "r", encoding="utf-8") as f:
            try:
                history = json.load(f)
            except Exception:
                history = []

    new_entry = {
        "task_id": task_id,
        "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        "source": source or filename,
        "task_type": task_type or "unknown"
    }
    history.append(new_entry)
    with open(history_path, "w", encoding="utf-8") as f:
        json.dump(history, f, ensure_ascii=False, indent=2)

    info(f"已追加 task_id 至 task_history.json")


def wait_for_task_complete(task_id, host, authorization, br, timeout=30, interval=5):
    """
    轮询查询任务状态直到完成、失败或超时
    :param task_id: str, 要查询的任务 ID
    :param host: str, 主机地址
    :param authorization: str, 鉴权 token
    :param br: BusinessRe 实例
    :param timeout: int, 超时时间（秒）
    :param interval: int, 查询间隔（秒）
    :return: dict，包含 status、video_url 或 error 信息
    """
    base_url = host + "/api/v2/hifly/video/task"
    ac = AssertCommon()
    start_time = time.time()

    while time.time() - start_time < timeout:
        query = urlencode({"task_id": task_id})
        url = f"{base_url}?{query}"
        try:
            # 添加 timeout 限制，防止卡住
            res = br.get(url, authorization)  # 👈 关键点：加 timeout

            # 接口响应结构检查
            res_json = res.json()
            print("[DEBUG] 请求返回：", res.text)
            code = res_json.get("code")
            ac.code_assert(0, code)

            status = res_json.get("status")
            info(f"[任务监控] task_id={task_id}, 当前状态={status}, 已等待 {int(time.time() - start_time)} 秒")

            if status == 3:
                return res_json
            elif status == 4:
                return {"status": 4, "task_id": task_id, "error": "作品失败"}
        except Exception as e:
            # 打印异常并继续等待，防止一次失败就中断
            info(f"[任务异常] 查询 task_id={task_id} 失败: {e}")
        time.sleep(interval)
    return {"status": -1, "task_id": task_id, "error": "超时等待未完成"}


def async_wait_for_task(task_id: str, host: str, authorization: str):
    """异步轮询任务状态"""
    thread = Thread(target=wait_for_task_complete, args=(task_id, host, authorization))
    thread.daemon = True
    thread.start()
    info("异步任务轮询已启动")

def get_video_duration(video_url):
    try:
        cmd = [
            "ffprobe",
            "-v", "error",
            "-show_entries", "format=duration",
            "-of", "json",
            video_url
        ]
        result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        output = json.loads(result.stdout)
        duration = float(output['format']['duration'])
        return round(duration, 2)
    except Exception as e:
        print(f"[ERROR] 获取视频时长失败: {e}")
        return None

